package cn.skyclass.beans
{
	import cn.skyclass.net.IRpcBean;
	
	import flash.events.EventDispatcher;
	
	import mx.utils.ObjectUtil;
	
	/**
	 * IFlexBean 的基本实现
	 */
	[Bindable]
	public class FlexBean extends EventDispatcher implements IFlexBean, IRpcBean
	{
		// implements IFlexBean method
		public function copyProperties(fromObj:Object):void{			
			if(fromObj == null){ return; }	    
			var claInfo:Object = ObjectUtil.getClassInfo(this);			
			var props:Array = claInfo["properties"];
			for each(var q:QName in props){
				try{		
					if(fromObj.hasOwnProperty(q.localName)){
						var oldValue:Object = this[q.localName];
						this[q.localName] = fromObj[q.localName];
						this.onPropertyCopied(q.localName, oldValue, fromObj[q.localName]);
					}
				}catch(err:Error){
	            	this.onCopyPropertyError(q.localName, err);
	            }
			}			
		}			
		
		// implements IRpcBean method
		public function fillWith(obj:Object):void{
	        if(obj == null){ return; }	        
	        for (var prop:String in obj){
	        	try{
	        		if(this.hasOwnProperty(prop)){
	        			this[prop] = obj[prop];
	        		}
	            	this.onPropertyFilled(prop, obj[prop]);
	            }catch(err:Error){	            	         	
	            	this.onFillPropertyError(prop, obj[prop], err);
	            }
	        }
		}
		
		public function encode4Rpc():void{
			var claInfo:Object = ObjectUtil.getClassInfo(this);			
			var props:Array = claInfo["properties"];
			for each(var q:QName in props){
				try{		
					var p:Object = this[q.localName];
					
					// deal with Number property witch is NaN
					if((p is Number) && isNaN(Number(p))){
						this[q.localName] = 0;
					}
				}catch(err:Error){
	            	trace(err);
	            }
			}	
		}
				
		
		///
		// 以下四个方法不做任何操作，主要用户子类扩展之用
		///
		
		/**
		 * 每个属性被填充后调用的方法
		 */
		protected function onPropertyFilled(propertyName:String, propertyValue:Object):void{
			// do nothing
		}
			
		/**
		 * 当填充属性数据发生错误时调用的方法
		 */
		protected function onFillPropertyError(propertyName:String, propertyValue:Object, err:Error):void{
			// do nothing
		}
		
		/**
		 * 每个属性被拷贝后调用的方法
		 */		
		protected function onPropertyCopied(propertyName:String, oldValue:Object, newValue:Object):void{
			// do nothing
		}		
		
		/**
		 * 当拷贝属性数据发生错误时调用的方法
		 */
		protected function onCopyPropertyError(propertyName:String, err:Error):void{ 
			// do nothing
		}
	}
}